package
{
    import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import mx.controls.Alert;
	import mx.core.UIComponent;
	import mx.managers.CursorManager;
	
	import spark.components.BorderContainer;
	import spark.components.Group;
	
	public class ResizeGroup extends BorderContainer
	{
		// the original state is fixed;when you click
		//it will be changed.
		private var state:String = ResizeConst.Fixed;
		private var currentCursorClass:Class;
		private var tempResizeStateBorder:ResizeStateBorder;
		[Bindable]
		public var parent_ui:Group;
		
		private var originalx:Number;
		private var originaly:Number;
		private var originalwidth:Number;
		private var originalheight:Number;
		
		
		private var resizeEdgeTolerance:Number;
		private var resizeCornerTolerance:Number;
		
		private var startResizingOnMouseDownFlag:Boolean;
		
		public function set State(value:String):void
		{
			this.state=value.toUpperCase();
			//when the value changed ;we come to here and change the view and state of the window;
			ViewChanged();
		}
		public function get State():String
		{
			return this.state;
		}
		public function ResizeGroup()
		{
			super();
			originalx=this.x;
			originaly=this.y;
			originalwidth=this.width;
			originalheight=this.height;
				
			this.registerEvents();
			
		}
		private function registerEvents():void
		{
			this.addEventListener(Event.ADDED_TO_STAGE,this.addedToStageHandler,false,0,true);
		}
		/**
		 * when stage is available
		 * */
		private function addedToStageHandler(event:Event):void
		{			
			this.registerUIEvents();
		}
		
		private function registerUIEvents():void
		{	//keydown events is used to control the following situations:
			//1.when user press "ESC", then the Reszie process will be stopped;this window will be fixed			
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN,this.stageKeyDownHandler,false,0,true);
			
			this.stage.addEventListener(MouseEvent.MOUSE_MOVE,this.stageMouseMoveHandler,false,0,true);
			
			this.stage.addEventListener(MouseEvent.MOUSE_UP,this.stageMouseUpHandler,false,0,true);
			
			this.stage.addEventListener(MouseEvent.MOUSE_DOWN,this.stageMouseDownHandler,false,0,true);
			
			//click events aims at handling the state of window ;
			//it will be change the window when you enter the initial window and click it;
			//convert the fixed state to be resizeable and draggable			
			this.stage.addEventListener(MouseEvent.CLICK,this.stageClickHandler,false,0,true);
		}		
		private function removeEvents():void
		{
			if(this.stage)//如果显示出来
			{
				
			
			}
			this.removeEventListener(Event.ADDED_TO_STAGE,this.addedToStageHandler);
		}
		//the following list shows all the Events Handler about the Resize and Drag process;
		private function stageKeyDownHandler(event:KeyboardEvent):void
		{
				
		}
		private function stageMouseMoveHandler(event:MouseEvent):void
		{
			var mouse_hit:Boolean =this.hitTestPoint(event.stageX,event.stageY);
			if(mouse_hit)
			{
				this.updateResizeCursor(event);
			}
			else { 
				if (this.currentCursorClass!=null) {	 
					CursorManager.removeAllCursors(); 		
					this.currentCursorClass = null;
					this.startResizingOnMouseDownFlag = false;		
				} 
			}
		}
		private function stageMouseUpHandler(event:MouseEvent):void
		{
					
		}
		private function stageMouseDownHandler(event:MouseEvent):void
		{
			var mousehit:Boolean =this.hitTestPoint(event.stageX,event.stageY);
			if(!mousehit)
			{
				return;
			}
			this.State=ResizeConst.Resizeable;
			//here
			
		
		}
		private function stageClickHandler(event:MouseEvent):void
		{
			var mousehit:Boolean =this.hitTestPoint(event.stageX,event.stageY);
			if(!mousehit)
			{
				return;
			}			
			this.State = ResizeConst.Draggable;
			//since we change the stage ,we need a function to change the Group
			//to make it seem to be resizeable and draggable
			var resize:ResizeStateBorder=new ResizeStateBorder();
			resize.width=this.width;
			resize.height=this.height;
			resize.x=this.x/2;//?
			resize.y=this.y/2;//?
			resize.setStyle("borderColor","#00FF00");
			this.parent_ui.addElement(resize);
			this.setStyle("borderAlpha","0");
			//change the state:
			this.state=ResizeConst.Resizeable;
		}
		// the above events end here
		private function ViewChanged():void
		{
			switch(this.stage)
			{
				
				case ResizeConst.Fixed:
						
					break;				
				default:
					
					
					break;
			}
		}
		
		private function updateResizeCursor(event:MouseEvent):void
		{
			var current_cursor:Class=this.currentCursorClass;
			var cursor_class:Class;
			
			var mouse_x:Number =this.mouseX;
			var mouse_y:Number =this.mouseY;
			
			//check whether we are close enough to any edge middle point or corner:
			//calculate 8 points
			var nwpt:Point= new Point(this.x,this.y);
			var npt:Point= new Point(this.x+this.width/2,this.y);
			var nept:Point=new Point(this.x+this.width,this.y);
			var ept:Point =new Point(this.x+this.width,this.y+this.height/2);
			var sept:Point=new Point(this.x+this.width,this.y+this.height);
			var spt:Point =new Point(this.x+this.width/2,this.y+this.height);
			var swpt:Point=new Point(this.x,this.y+this.height);
			var wpt:Point=new Point(this.x,this.y+this.height/2);
			var pts:Array=[nwpt,npt,nept,ept,sept,spt,swpt,wpt];
			var dirction:Array=["nw","n","ne","e","se","s","sw","w"];
			
			var result:Array=new Array();
			
			var mousept:Point=new Point(event.stageX,event.stageY);
			
			for(var i:int=0;i<pts.length;i++)
			{			
				if( Point.distance(pts[i],mousept)<5)
				{
					result.push(dirction[i]);
				}
			}
			if(result.length<=0) 
			{	
				this.startResizingOnMouseDownFlag = false;		
				this.currentCursorClass = null;	
				CursorManager.removeAllCursors();
				return;
			}
			if(result.length>1)
			{
				Alert.show("窗体太小了");
			}		
			else
			{
				//here we change the style of mouse
				switch(result[0])
				{
					case dirction[0]:
						cursor_class = ResizeCursorNW;
						break;
					case dirction[1]:
						cursor_class = ResizeCursorN;
						break;
					case dirction[2]:
						cursor_class = ResizeCursorNE;
						break;
					case dirction[3]:
						cursor_class = ResizeCursorE;
						break;
					case dirction[4]:
						cursor_class = ResizeCursorSE;
						break;
					case dirction[5]:
						cursor_class = ResizeCursorS;
						break;
					case dirction[6]:
						cursor_class = ResizeCursorSW;
						break;
					case dirction[7]:
						cursor_class = ResizeCursorW;
						break;
				}
				
				this.startResizingOnMouseDownFlag = true;
				
				// if our needed cursor changes, remove the old one to avoid flickering between the two types.
				// this happens for example when you reach a corner of teh popup after you followed an edge with the mouse. 
				if (cursor_class != current_cursor) {
					CursorManager.removeAllCursors();		 			 
				}
				
				
				// okay, we know which cursor we need to show, so lets show it
				//var cursor_class:Class = Assets.getAsset( needed_cursor_type ); 					
				//var cursor_w:Number = Assets.getImageSize(needed_cursor_type)['width'];
				//var cursor_h:Number = Assets.getImageSize(needed_cursor_type)['height'];
				CursorManager.setCursor( cursor_class, 2, -new cursor_class().width/2, -new cursor_class().height/2  );		
				
				
				// remember our cursor decision for the next check, because as described above,
				// we need to react on changes of the cursor type on corners to avoid flickering  
				this.currentCursorClass = cursor_class;	
			}
		}
	}
}